home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickDraw3D 1.6 SDK / Mac SampleCode New for 1.6 / FogStyleSample / Source / QD3D_Support.c < prev   
Encoding:
C/C++ Source or Header  |  1999-05-18  |  24.1 KB  |  866 lines  |  [TEXT/CWIE]

  1. /****************************/
  2. /*       QD3D SUPPORT.C        */
  3. /* By Brian Greenstone      */
  4. /****************************/
  5.  
  6.  
  7. /****************************/
  8. /*    EXTERNALS             */
  9. /****************************/
  10.  
  11. #include <QD3D.h>
  12. #include <QD3DGroup.h>
  13. #include <QD3DLight.h>
  14. #include <QD3DTransform.h>
  15. #include <QD3DStorage.h>
  16. #include <QD3DMath.h>
  17. #include <QD3DErrors.h>
  18. #include <Rave.h>
  19. #include <ImageCompression.h>
  20. #include <PictUtils.h>
  21.  
  22. #include <timer.h>
  23. #include "myglobals.h"
  24. #include "misc.h"
  25. #include "qd3d_support.h"
  26.  
  27. extern    WindowPtr            gModelWindow;
  28.  
  29. /****************************/
  30. /*    PROTOTYPES            */
  31. /****************************/
  32.  
  33. static void CreateDrawContext(QD3DViewDefType *viewDefPtr);
  34. static void SetStyles(QD3DStyleDefType *styleDefPtr);
  35. static void CreateCamera(QD3DCameraDefType *cameraDefPtr);
  36. static void CreateLights(QD3DLightDefType *lightDefPtr);
  37. static void CreateView(QD3DSetupInputType *setupDefPtr);
  38. static void CreateTexturePixmap(PicHandle pict,unsigned long mapSizeX,
  39.                              unsigned long mapSizeY, TQ3StoragePixmap *bMap);
  40. static void TraverseDisplayGroupInfo(TQ3Object theGroup);
  41. static void ShowMeshInfo(TQ3Object theMesh);
  42. static void ShowAttributeInfo(TQ3AttributeSet theAttribute);
  43. static void ShowTriMeshInfo(TQ3Object theTriMesh);
  44. static void GWorldToBMap(GWorldPtr pGWorld, TQ3StoragePixmap *bMap);
  45. static void DrawPICTIntoMipmap(PicHandle pict,long width, long height, TQ3Mipmap *mipmap);
  46.  
  47.  
  48. /****************************/
  49. /*    CONSTANTS             */
  50. /****************************/
  51.  
  52.  
  53. /*********************/
  54. /*    VARIABLES      */
  55. /*********************/
  56.  
  57. static TQ3CameraObject            gQD3D_CameraObject;
  58. static TQ3GroupObject            gQD3D_LightGroup;
  59. static TQ3ViewObject            gQD3D_ViewObject;
  60. static TQ3DrawContextObject        gQD3D_DrawContext;
  61. static TQ3RendererObject        gQD3D_RendererObject;
  62. static TQ3ShaderObject            gQD3D_ShaderObject;
  63. static    TQ3StyleObject            gQD3D_BackfacingStyle;
  64. static    TQ3StyleObject            gQD3D_FillStyle;
  65. static    TQ3StyleObject            gQD3D_InterpolationStyle;
  66.  
  67. float    gFramesPerSecond = DEFAULT_FPS;                // this is used to maintain a constant timing velocity as frame rates differ
  68.  
  69.  
  70.  
  71.  
  72. //=======================================================================================================
  73. //=============================== VIEW WINDOW SETUP STUFF ===============================================
  74. //=======================================================================================================
  75.  
  76.  
  77. /************** SETUP QD3D WINDOW *******************/
  78.  
  79. void QD3D_SetupWindow(QD3DSetupInputType *setupDefPtr, QD3DSetupOutputType *outputPtr)
  80. {
  81.     CreateView(setupDefPtr);
  82.     Q3InteractiveRenderer_SetDoubleBufferBypass(gQD3D_RendererObject,kQ3True);        // let hardware go fast    
  83.     CreateCamera(&setupDefPtr->camera);                                        // create new CAMERA object
  84.     CreateLights(&setupDefPtr->lights);
  85.     SetStyles(&setupDefPtr->styles);    
  86.     
  87.  
  88.                 /* DISPOSE OF EXTRA REFERENCES */
  89.                 
  90.     Q3Object_Dispose(gQD3D_RendererObject);                // (is contained w/in gQD3D_ViewObject)
  91.  
  92.     
  93.                 /* PASS BACK INFO */
  94.                 
  95.     outputPtr->viewObject = gQD3D_ViewObject;
  96.     outputPtr->interpolationStyle = gQD3D_InterpolationStyle;
  97.     outputPtr->fillStyle = gQD3D_FillStyle;
  98.     outputPtr->backfacingStyle = gQD3D_BackfacingStyle;
  99.     outputPtr->shaderObject = gQD3D_ShaderObject;
  100.     outputPtr->cameraObject = gQD3D_CameraObject;
  101.     outputPtr->lightGroup = gQD3D_LightGroup;
  102.     outputPtr->drawContext = gQD3D_DrawContext;
  103.     outputPtr->window = setupDefPtr->view.displayWindow;        // remember which window
  104.     outputPtr->paneClip = setupDefPtr->view.paneClip;
  105. }
  106.  
  107.  
  108. /***************** QD3D_DisposeWindowSetup ***********************/
  109. //
  110. // Disposes of all data created by QD3D_SetupWindow
  111. //
  112.  
  113. void QD3D_DisposeWindowSetup(QD3DSetupOutputType *data)
  114. {
  115.     Q3Object_Dispose(data->viewObject);
  116.     Q3Object_Dispose(data->interpolationStyle);
  117.     Q3Object_Dispose(data->backfacingStyle);
  118.     Q3Object_Dispose(data->fillStyle);
  119.     Q3Object_Dispose(data->cameraObject);
  120.     Q3Object_Dispose(data->lightGroup);
  121.     Q3Object_Dispose(data->drawContext);
  122.     Q3Object_Dispose(data->shaderObject);
  123. }
  124.  
  125.  
  126. /******************* CREATE GAME VIEW *************************/
  127.  
  128. static void CreateView(QD3DSetupInputType *setupDefPtr)
  129. {
  130. TQ3Status    myErr;
  131. unsigned long    hints;
  132.  
  133.                 /* CREATE NEW VIEW OBJECT */
  134.                 
  135.     gQD3D_ViewObject = Q3View_New();
  136.     if (gQD3D_ViewObject == nil)
  137.         DoFatalAlert("\pQ3View_New failed!");
  138.  
  139.  
  140.             /* CREATE & SET DRAW CONTEXT */
  141.     
  142.     CreateDrawContext(&setupDefPtr->view);                                 // init draw context
  143.     
  144.     myErr = Q3View_SetDrawContext(gQD3D_ViewObject, gQD3D_DrawContext);            // assign context to view
  145.     if (myErr == kQ3Failure)
  146.         DoFatalAlert("\pQ3View_SetDrawContext Failed!");
  147.  
  148.  
  149.  
  150.             /* CREATE & SET RENDERER */
  151.  
  152.     gQD3D_RendererObject = Q3Renderer_NewFromType(setupDefPtr->view.rendererType);    // create new RENDERER object
  153.     if (gQD3D_RendererObject == nil)
  154.     {
  155.         QD3D_ShowError("\pQ3Renderer_NewFromType Failed!", true);
  156.         CleanQuit();
  157.     }
  158.  
  159.     myErr = Q3View_SetRenderer(gQD3D_ViewObject, gQD3D_RendererObject);                // assign renderer to view
  160.     if (myErr == kQ3Failure)
  161.         DoFatalAlert("\pQ3View_SetRenderer Failed!");
  162.  
  163.         /* SET RENDERER FEATURES */
  164.         
  165.     Q3InteractiveRenderer_GetRAVEContextHints(gQD3D_RendererObject, &hints);
  166.     hints &= ~kQAContext_NoZBuffer;                 // Z buffer is on 
  167.     hints &= ~kQAContext_DeepZ;                     // Z buffer is not deep, ergo it's shallow 
  168.     hints |= kQAContext_NoDither;                     // No Dither 
  169.     Q3InteractiveRenderer_SetRAVEContextHints(gQD3D_RendererObject, hints);    
  170.     
  171.     Q3InteractiveRenderer_SetRAVETextureFilter(gQD3D_RendererObject,kQATextureFilter_Mid);    // fast texturing
  172.     Q3InteractiveRenderer_SetDoubleBufferBypass(gQD3D_RendererObject,kQ3True);
  173. }
  174.  
  175.  
  176. /**************** CREATE SKELETON DRAW CONTEXT *********************/
  177.  
  178. static void CreateDrawContext(QD3DViewDefType *viewDefPtr)
  179. {
  180. TQ3DrawContextData        drawContexData;
  181. TQ3MacDrawContextData    myMacDrawContextData;
  182. Rect                    r;
  183.  
  184.     r = viewDefPtr->displayWindow->portRect;
  185.  
  186.  
  187.             /* FILL IN DRAW CONTEXT DATA */
  188.  
  189.     drawContexData.clearImageMethod = kQ3ClearMethodWithColor;                // how to clear
  190.     drawContexData.clearImageColor = viewDefPtr->clearColor;                // color to clear to
  191.     drawContexData.pane.min.x = r.left+viewDefPtr->paneClip.left;            // set bounds?
  192.     drawContexData.pane.max.x = r.right-viewDefPtr->paneClip.right;
  193.     drawContexData.pane.min.y = r.top+viewDefPtr->paneClip.top;
  194.     drawContexData.pane.max.y = r.bottom-viewDefPtr->paneClip.bottom;
  195.     drawContexData.paneState = kQ3True;                                        // use bounds?
  196.     drawContexData.maskState = kQ3False;                                    // no mask
  197.     drawContexData.doubleBufferState = kQ3True;                                // double buffering
  198.  
  199.     myMacDrawContextData.drawContextData = drawContexData;                    // set MAC specifics
  200.     myMacDrawContextData.window = (CWindowPtr)viewDefPtr->displayWindow;    // assign window to draw to
  201.     myMacDrawContextData.library = kQ3Mac2DLibraryNone;                        // use standard QD libraries (no GX crap!)
  202.     myMacDrawContextData.viewPort = nil;                                    // (for GX only)
  203.     myMacDrawContextData.grafPort = (CWindowPtr)viewDefPtr->displayWindow;    // assign grafport
  204.  
  205.  
  206.             /* CREATE DRAW CONTEXT */
  207.  
  208.     gQD3D_DrawContext = Q3MacDrawContext_New(&myMacDrawContextData);
  209.     if (gQD3D_DrawContext == nil)
  210.         DoFatalAlert("\pQ3MacDrawContext_New Failed!");
  211. }
  212.  
  213.  
  214. /**************** SET STYLES ****************/
  215. //
  216. // Creates style objects which define how the scene is to be rendered.
  217. // It also sets the shader object.
  218. //
  219.  
  220. static void SetStyles(QD3DStyleDefType *styleDefPtr)
  221. {
  222.  
  223.                 /* SET INTERPOLATION (FOR SHADING) */
  224.                     
  225.     gQD3D_InterpolationStyle = Q3InterpolationStyle_New(styleDefPtr->interpolation);
  226.     if (gQD3D_InterpolationStyle == nil)
  227.         DoFatalAlert("\pQ3InterpolationStyle_New Failed!");
  228.  
  229.                     /* SET BACKFACING */
  230.  
  231.     gQD3D_BackfacingStyle = Q3BackfacingStyle_New(styleDefPtr->backfacing);
  232.     if (gQD3D_BackfacingStyle == nil )
  233.         DoFatalAlert("\pQ3BackfacingStyle_New Failed!");
  234.  
  235.  
  236.                 /* SET POLYGON FILL STYLE */
  237.                         
  238.     gQD3D_FillStyle = Q3FillStyle_New(styleDefPtr->fill);
  239.     if ( gQD3D_FillStyle == nil )
  240.         DoFatalAlert("\p Q3FillStyle_New Failed!");
  241.  
  242.  
  243.                     /* SET THE SHADER TO USE */
  244.  
  245.     switch(styleDefPtr->illuminationType)
  246.     {
  247.         case    kQ3IlluminationTypePhong:
  248.                 gQD3D_ShaderObject = Q3PhongIllumination_New();
  249.                 if ( gQD3D_ShaderObject == nil )
  250.                     DoFatalAlert("\p Q3PhongIllumination_New Failed!");
  251.                 break;
  252.                 
  253.         case    kQ3IlluminationTypeLambert:
  254.                 gQD3D_ShaderObject = Q3LambertIllumination_New();
  255.                 if ( gQD3D_ShaderObject == nil )
  256.                     DoFatalAlert("\p Q3LambertIllumination_New Failed!");
  257.                 break;
  258.                 
  259.         case    kQ3IlluminationTypeNULL:
  260.                 gQD3D_ShaderObject = Q3NULLIllumination_New();
  261.                 if ( gQD3D_ShaderObject == nil )
  262.                     DoFatalAlert("\p Q3NullIllumination_New Failed!");
  263.                 break;
  264.     }    
  265. }
  266.  
  267.  
  268.  
  269. /****************** CREATE CAMERA *********************/
  270.  
  271. static void CreateCamera(QD3DCameraDefType *cameraDefPtr)
  272. {
  273. TQ3CameraData                    myCameraData;
  274. TQ3ViewAngleAspectCameraData    myViewAngleCameraData;
  275. TQ3Area                            pane;
  276. TQ3Status                        status;
  277. TQ3Status    myErr;
  278.  
  279.     status = Q3DrawContext_GetPane(gQD3D_DrawContext,&pane);                // get window pane info
  280.     if (status == kQ3Failure)
  281.         DoFatalAlert("\pQ3DrawContext_GetPane Failed!");
  282.  
  283.  
  284.                 /* FILL IN CAMERA DATA */
  285.                 
  286.     myCameraData.placement.cameraLocation = cameraDefPtr->from;            // set camera coords
  287.     myCameraData.placement.pointOfInterest = cameraDefPtr->to;            // set target coords
  288.     myCameraData.placement.upVector = cameraDefPtr->up;                    // set a vector that's "up"
  289.     myCameraData.range.hither = cameraDefPtr->hither;                    // set frontmost Z dist
  290.     myCameraData.range.yon = cameraDefPtr->yon;                            // set farthest Z dist
  291.     myCameraData.viewPort.origin.x = -1.0;                                // set view origins?
  292.     myCameraData.viewPort.origin.y = 1.0;
  293.     myCameraData.viewPort.width = 2.0;
  294.     myCameraData.viewPort.height = 2.0;
  295.  
  296.     myViewAngleCameraData.cameraData = myCameraData;
  297.     myViewAngleCameraData.fov = cameraDefPtr->fov;                        // larger = more fisheyed
  298.     myViewAngleCameraData.aspectRatioXToY =
  299.                 (pane.max.x-pane.min.x)/(pane.max.y-pane.min.y);
  300.  
  301.     gQD3D_CameraObject = Q3ViewAngleAspectCamera_New(&myViewAngleCameraData);     // create new camera
  302.     if (gQD3D_CameraObject == nil)
  303.         DoFatalAlert("\pQ3ViewAngleAspectCamera_New failed!");
  304.         
  305.     myErr = Q3View_SetCamera(gQD3D_ViewObject, gQD3D_CameraObject);        // assign camera to view
  306.     if (myErr == kQ3Failure)
  307.         DoFatalAlert("\pQ3View_SetCamera Failed!");
  308.  
  309. }
  310.  
  311.  
  312. /********************* CREATE LIGHTS ************************/
  313.  
  314. static void CreateLights(QD3DLightDefType *lightDefPtr)
  315. {
  316. TQ3GroupPosition        myGroupPosition;
  317. TQ3LightData            myLightData;
  318. TQ3DirectionalLightData    myDirectionalLightData;
  319. TQ3LightObject            myLight;
  320. short                    i;
  321. TQ3Status    myErr;
  322.  
  323.  
  324.             /* CREATE NEW LIGHT GROUP */
  325.             
  326.     gQD3D_LightGroup = Q3LightGroup_New();                        // make new light group
  327.     if ( gQD3D_LightGroup == nil )
  328.         DoFatalAlert("\p Q3LightGroup_New Failed!");
  329.  
  330.  
  331.     myLightData.isOn = kQ3True;                                    // light is ON
  332.     
  333.             /************************/
  334.             /* CREATE AMBIENT LIGHT */
  335.             /************************/
  336.  
  337.     if (lightDefPtr->ambientBrightness != 0)                        // see if ambient exists
  338.     {
  339.         myLightData.color = lightDefPtr->ambientColor;                // set color of light
  340.         myLightData.brightness = lightDefPtr->ambientBrightness;    // set brightness value
  341.         myLight = Q3AmbientLight_New(&myLightData);                    // make it
  342.         if ( myLight == nil )
  343.             DoFatalAlert("\pQ3AmbientLight_New Failed!");
  344.  
  345.         myGroupPosition = Q3Group_AddObject(gQD3D_LightGroup, myLight);    // add to group
  346.         if ( myGroupPosition == 0 )
  347.             DoFatalAlert("\p Q3Group_AddObject Failed!");
  348.  
  349.         Q3Object_Dispose(myLight);                                    // dispose of light
  350.  
  351.     }
  352.  
  353.             /**********************/
  354.             /* CREATE FILL LIGHTS */
  355.             /**********************/
  356.             
  357.     for (i=0; i < lightDefPtr->numFillLights; i++)
  358.     {        
  359.         myLightData.color = lightDefPtr->fillColor[i];                        // set color of light
  360.         myLightData.brightness = lightDefPtr->fillBrightness[i];            // set brightness
  361.         myDirectionalLightData.lightData = myLightData;                        // refer to general light info
  362.         myDirectionalLightData.castsShadows = kQ3False;                        // no shadows
  363.         myDirectionalLightData.direction =  lightDefPtr->fillDirection[i];    // set fill vector
  364.         myLight = Q3DirectionalLight_New(&myDirectionalLightData);            // make it
  365.         if ( myLight == nil )
  366.             DoFatalAlert("\p Q3DirectionalLight_New Failed!");
  367.  
  368.         myGroupPosition = Q3Group_AddObject(gQD3D_LightGroup, myLight);        // add to group
  369.         if ( myGroupPosition == 0 )
  370.             DoFatalAlert("\p Q3Group_AddObject Failed!");
  371.  
  372.         Q3Object_Dispose(myLight);                                            // dispose of light
  373.     }
  374.     
  375.             /* ASSIGN LIGHT GROUP TO VIEW */
  376.             
  377.     myErr = Q3View_SetLightGroup(gQD3D_ViewObject, gQD3D_LightGroup);        // assign light group to view
  378.     if (myErr == kQ3Failure)
  379.         DoFatalAlert("\pQ3View_SetLightGroup Failed!");        
  380.  
  381. }
  382.  
  383. /******************** QD3D CHANGE DRAW SIZE *********************/
  384. //
  385. // Changes size of stuff to fit new window size.
  386. //
  387.  
  388. void QD3D_ChangeDrawSize(QD3DSetupOutputType *setupInfo)
  389. {
  390. Rect            r;
  391. TQ3Area            pane;
  392. TQ3ViewAngleAspectCameraData    cameraData;
  393.  
  394.             /* CHANGE DRAW CONTEXT PANE SIZE */
  395.             
  396.     r = setupInfo->window->portRect;                            // get size of window
  397.     pane.min.x = r.left+setupInfo->paneClip.left;                                        // set pane size
  398.     pane.max.x = r.right-setupInfo->paneClip.right;
  399.     pane.min.y = r.top+setupInfo->paneClip.top;
  400.     pane.max.y = r.bottom-setupInfo->paneClip.bottom;
  401.     Q3DrawContext_SetPane(setupInfo->drawContext,&pane);        // update pane in draw context
  402.  
  403.  
  404.                 /* CHANGE CAMERA ASPECT RATIO */
  405.                 
  406.     Q3ViewAngleAspectCamera_GetData(setupInfo->cameraObject,&cameraData);            // get camera data
  407.     cameraData.aspectRatioXToY = (pane.max.x-pane.min.x)/(pane.max.y-pane.min.y);    // set new aspect ratio
  408.     Q3ViewAngleAspectCamera_SetData(setupInfo->cameraObject,&cameraData);            // set new camera data
  409. }
  410.  
  411.  
  412. /******************* QD3D DRAW SCENE *********************/
  413.  
  414. void QD3D_DrawScene(QD3DSetupOutputType *setupInfo, void (*drawRoutine)(QD3DSetupOutputType *))
  415. {
  416. TQ3Status                myStatus;
  417. TQ3ViewStatus            myViewStatus;
  418.  
  419.             /* START RENDERING */
  420.  
  421. //startTrace("test.tt6");
  422.  
  423.     myStatus = Q3View_StartRendering(setupInfo->viewObject);            
  424.     if ( myStatus == kQ3Failure )
  425.     {
  426.         DoFatalAlert("\p Q3View_StartRendering Failed!");
  427.     }
  428.     
  429.             /***************/
  430.             /* RENDER LOOP */
  431.             /***************/
  432.     do
  433.     {
  434.                 /* DRAW STYLES */
  435.                 
  436.         myStatus = Q3Style_Submit(setupInfo->interpolationStyle,setupInfo->viewObject);
  437.         if ( myStatus == kQ3Failure )
  438.             DoFatalAlert("\p Q3Style_Submit Failed!");
  439.             
  440.         myStatus = Q3Style_Submit(setupInfo->backfacingStyle,setupInfo->viewObject);
  441.         if ( myStatus == kQ3Failure )
  442.             DoFatalAlert("\p Q3Style_Submit Failed!");
  443.             
  444.         myStatus = Q3Style_Submit(setupInfo->fillStyle, setupInfo->viewObject);
  445.         if ( myStatus == kQ3Failure )
  446.             DoFatalAlert("\p Q3Style_Submit Failed!");
  447.  
  448.         myStatus = Q3Shader_Submit(setupInfo->shaderObject, setupInfo->viewObject);
  449.         if ( myStatus == kQ3Failure )
  450.             DoFatalAlert("\p Q3Shader_Submit Failed!");
  451.  
  452.  
  453.             /* CALL INPUT DRAW FUNCTION */
  454.  
  455.         drawRoutine(setupInfo);
  456.  
  457.         myViewStatus = Q3View_EndRendering(setupInfo->viewObject);
  458.         
  459.     } while ( myViewStatus == kQ3ViewStatusRetraverse );
  460.     
  461. //stopTrace();
  462. //CleanQuit();
  463. }
  464.  
  465.  
  466. //=======================================================================================================
  467. //=============================== MISC ==================================================================
  468. //=======================================================================================================
  469.  
  470. /************** QD3D CALC FRAMES PER SECOND *****************/
  471.  
  472. float    QD3D_CalcFramesPerSecond(void)
  473. {
  474. UnsignedWide    wide;
  475. unsigned long    now;
  476. static    unsigned long then = 0;
  477.  
  478.     Microseconds(&wide);
  479.     now = wide.lo;
  480.     if (then != 0)
  481.     {
  482.         gFramesPerSecond = (float)1000000.0/(float)(now-then);
  483.         if (gFramesPerSecond < DEFAULT_FPS)            // (avoid divide by 0's later)
  484.             gFramesPerSecond = DEFAULT_FPS;
  485.     
  486.     }
  487.     else
  488.         gFramesPerSecond = DEFAULT_FPS;
  489.         
  490.     then = now;                                // remember time    
  491.     
  492.     return(gFramesPerSecond);
  493. }
  494.  
  495.  
  496. #pragma mark ========== error stuff ===========
  497.  
  498.  
  499. /******************* QD3D: SHOW ERROR *************************/
  500. //
  501. // Returns true if Error, false if just a warning.
  502. //
  503.  
  504. Boolean QD3D_ShowError(Str255 errString, Boolean showWarnings)
  505. {
  506. TQ3Error    err;
  507. TQ3Warning    warning;
  508. Str255        numStr;
  509.  
  510.         /* DO ERRORS */
  511.         
  512.     err = Q3Error_Get(nil);
  513.     if (err != 0)
  514.     {
  515.         DoAlert(errString);
  516.         switch(err)
  517.         {
  518.             case    kQ3ErrorViewNotStarted:
  519.                     DoFatalAlert("\pError:kQ3ErrorViewNotStarted");
  520.                     break;
  521.                     
  522.             case    kQ3ErrorOutOfMemory:
  523.                     DoFatalAlert("\pError:kQ3ErrorOutOfMemory");
  524.                     break;
  525.                     
  526.             default:
  527.                     ShowSystemErr(err);
  528.         }
  529.         return(true);
  530.     }
  531.     
  532.         /* DO WARNINGS */
  533.     else
  534.     {
  535.         if (!showWarnings)
  536.             return(false);
  537.         
  538.         DoAlert(errString);
  539.         warning = Q3Warning_Get(nil);
  540.         switch(warning)
  541.         {
  542.             case    kQ3WarningFunctionalityNotSupported:
  543.                     DoAlert("\pWarning: kQ3WarningFunctionalityNotSupported");
  544.                     break;
  545.                     
  546.             default:
  547.                     NumToString(err, numStr);
  548.                     DoAlert (numStr);
  549.         }
  550.         return(false);
  551.     }
  552.     
  553.     
  554. }
  555.  
  556.  
  557. /************ QD3D: SHOW RECENT ERROR *******************/
  558.  
  559. void QD3D_ShowRecentError(void)
  560. {
  561. TQ3Error    q3Err;
  562. Str255        s;
  563.     
  564.     q3Err = Q3Error_Get(nil);
  565.     if (q3Err == kQ3ErrorOutOfMemory)
  566.         QD3D_DoMemoryError();
  567.     else
  568.     if (q3Err == kQ3ErrorMacintoshError)
  569.         DoFatalAlert("\pkQ3ErrorMacintoshError");
  570.     else
  571.     if (q3Err != 0)
  572.     {
  573.         NumToString(q3Err,s);
  574.         DoFatalAlert(s);
  575.     }
  576. }
  577.  
  578.  
  579. //=======================================================================================================
  580. //=============================== TEXTURE MAP STUFF =====================================================
  581. //=======================================================================================================
  582.  
  583. #pragma mark ########## textures #############
  584.  
  585. /**************** QD3D GET TEXTURE MAP ***********************/
  586. //
  587. // Loads a PICT resource and returns a shader object which is
  588. // based on the PICT converted to a texture map.
  589. //
  590. // INPUT: textureRezID = resource ID of texture PICT to get.
  591. //            myFSSpec != nil if want to load PICT from file instead
  592. //
  593. // OUTPUT: TQ3ShaderObject = shader object for texture map.  nil == error.
  594. //
  595.  
  596. TQ3SurfaceShaderObject    QD3D_GetTextureMap(long    textureRezID, FSSpec *myFSSpec)
  597. {
  598. PicHandle            picture;
  599. TQ3SurfaceShaderObject        shader;
  600. long                pictSize,headerSize;
  601. OSErr                iErr;
  602. short                fRefNum;
  603. char                pictHeader[512];
  604.  
  605.     if (myFSSpec == nil)
  606.     {
  607.                     /* LOAD PICT REZ */
  608.         
  609.         picture = GetPicture (textureRezID);
  610.         if (picture == nil)
  611.             DoFatalAlert("\pUnable to load texture PICT resource");
  612.     }
  613.     else
  614.     {
  615.                 /* LOAD PICT FROM FILE */
  616.     
  617.         iErr = FSpOpenDF(myFSSpec,fsCurPerm,&fRefNum);
  618.         if (iErr)
  619.         {
  620.             DoAlert("\pSorry, can open that PICT file!");
  621.             return(nil);
  622.         }
  623.  
  624.         if    (GetEOF(fRefNum,&pictSize) != noErr)        // get size of file        
  625.             goto err;
  626.                 
  627.         headerSize = 512;                    // check the header                    
  628.         if (FSRead(fRefNum,&headerSize,pictHeader) != noErr)
  629.             goto err;
  630.  
  631.         if ((pictSize -= 512) <= 0)
  632.             goto err;
  633.             
  634.         if ((picture = (PicHandle)NewHandle(pictSize)) == nil)
  635.         {
  636.             DoAlert("\pSorry, not enough memory to read PICT file!");
  637.             return(nil);
  638.         }
  639.         HLock((Handle)picture);
  640.             
  641.         if (FSRead(fRefNum,&pictSize,*picture) != noErr)
  642.         {
  643.             DisposeHandle((Handle)picture);
  644.             goto err;
  645.         }
  646.             
  647.         FSClose(fRefNum);        
  648.     }
  649.     
  650.     
  651.     shader = QD3D_PICTToTexture(picture);
  652.         
  653.     if (myFSSpec == nil)
  654.         ReleaseResource ((Handle) picture);
  655.     else
  656.         KillPicture(picture);    
  657.  
  658.     return(shader);    
  659.     
  660. err:
  661.     DoAlert("\pSorry, error reading PICT file!");
  662.     return(nil);
  663. }
  664.  
  665.  
  666. /**************** QD3D PICT TO TEXTURE ***********************/
  667. //
  668. //
  669. // INPUT: picture = handle to PICT.
  670. //
  671. // OUTPUT: TQ3ShaderObject = shader object for texture map.
  672. //
  673.  
  674. TQ3SurfaceShaderObject    QD3D_PICTToTexture(PicHandle picture)
  675. {
  676. TQ3Mipmap                 mipmap;
  677. TQ3TextureObject        texture;
  678. TQ3SurfaceShaderObject    shader;
  679. long                    width,height;
  680.  
  681.  
  682.             /* MAKE INTO STORAGE MIPMAP */
  683.  
  684.     width = (**picture).picFrame.right  - (**picture).picFrame.left;        // calc dimensions of mipmap
  685.     height = (**picture).picFrame.bottom - (**picture).picFrame.top;
  686.         
  687.     DrawPICTIntoMipmap (picture, width, height, &mipmap);
  688.         
  689.  
  690.             /* MAKE NEW PIXMAP TEXTURE */
  691.             
  692.     texture = Q3MipmapTexture_New(&mipmap);                            // make new mipmap    
  693.     if (texture == nil)
  694.         DoFatalAlert("\pQD3D_PICTToTexture: Q3MipmapTexture_New failed!");
  695.         
  696.     shader = Q3TextureShader_New (texture);
  697.     if (shader == nil)
  698.         DoFatalAlert("\pError calling Q3TextureShader_New!");
  699.  
  700.     Q3Object_Dispose (texture);
  701.     Q3Object_Dispose (mipmap.image);            // disposes of extra reference to storage obj
  702.  
  703.     return(shader);    
  704. }
  705.  
  706.  
  707. /**************** QD3D GWORLD TO TEXTURE ***********************/
  708. //
  709. // INPUT: picture = handle to PICT.
  710. //
  711. // OUTPUT: TQ3ShaderObject = shader object for texture map.
  712. //
  713.  
  714. TQ3SurfaceShaderObject    QD3D_GWorldToTexture(GWorldPtr theGWorld, Boolean pointToGWorld)
  715. {
  716. TQ3Mipmap                     mipmap;
  717. TQ3TextureObject            texture;
  718. TQ3SurfaceShaderObject        shader;
  719.  
  720.             /* CREATE MIPMAP */
  721.             
  722.     QD3D_GWorldToMipMap(theGWorld,&mipmap, pointToGWorld);
  723.  
  724.  
  725.             /* MAKE NEW MIPMAP TEXTURE */
  726.             
  727.     texture = Q3MipmapTexture_New(&mipmap);                            // make new mipmap    
  728.     if (texture == nil)
  729.         DoFatalAlert("\pQD3D_GWorldToTexture: Q3MipmapTexture_New failed!");
  730.             
  731.     shader = Q3TextureShader_New(texture);
  732.     if (shader == nil)
  733.         DoFatalAlert("\pError calling Q3TextureShader_New!");
  734.  
  735.     Q3Object_Dispose (texture);
  736.     Q3Object_Dispose (mipmap.image);                    // dispose of extra ref to storage object
  737.  
  738.     return(shader);    
  739. }
  740.  
  741.  
  742. /******************** DRAW PICT INTO MIPMAP ********************/
  743. //
  744. // OUTPUT: mipmap = new mipmap holding texture image
  745. //
  746.  
  747. static void DrawPICTIntoMipmap(PicHandle pict,long width, long height, TQ3Mipmap *mipmap)
  748. {
  749. Rect                     rectGW;
  750. GWorldPtr                 pGWorld;
  751. PixMapHandle             hPixMap;
  752. OSErr                    myErr;
  753. GDHandle                oldGD;
  754. GWorldPtr                oldGW;
  755. long                    bytesNeeded;
  756. PictInfo                thePictInfo;
  757. short                    depth;
  758.  
  759.     GetGWorld(&oldGW, &oldGD);                                        // save current port
  760.  
  761.  
  762.                 /* GET PICT INFO TO FIND COLOR DEPTH */
  763.                 
  764.     myErr = GetPictInfo(pict, &thePictInfo, 0, 0, systemMethod, 0);
  765.     if (myErr)
  766.         DoFatalAlert("\pDrawPICTIntoMipmap: GetPictInfo failed!");
  767.  
  768.     depth = thePictInfo.depth;
  769.     
  770.     if (thePictInfo.commentHandle)                                    // free pict info
  771.         DisposeHandle((Handle)thePictInfo.commentHandle);
  772.     if (thePictInfo.fontHandle)
  773.         DisposeHandle((Handle)thePictInfo.fontHandle);
  774.     if (thePictInfo.fontNamesHandle)
  775.         DisposeHandle((Handle)thePictInfo.fontNamesHandle);
  776.     if (thePictInfo.theColorTable)
  777.         DisposeCTable(thePictInfo.theColorTable);
  778.  
  779.  
  780.  
  781.                 /* CREATE A GWORLD TO DRAW INTO */
  782.  
  783.     SetRect(&rectGW, 0, 0, width, height);                            // set dimensions
  784.     bytesNeeded = width * height * 2;
  785.     myErr = NewGWorld(&pGWorld, depth, &rectGW, 0, 0, 0L);            // make gworld
  786.     if (myErr)
  787.         DoFatalAlert("\pDrawPICTIntoMipmap: NewGWorld failed!");
  788.     
  789.     hPixMap = GetGWorldPixMap(pGWorld);                                // get gworld's pixmap
  790.  
  791.  
  792.             /* DRAW PICTURE INTO GWORLD */
  793.             
  794.     SetGWorld(pGWorld, nil);    
  795.     LockPixels(hPixMap);
  796.     EraseRect(&rectGW);
  797.     DrawPicture(pict, &rectGW);
  798.  
  799.  
  800.             /* MAKE A MIPMAP FROM GWORLD */
  801.             
  802.     QD3D_GWorldToMipMap(pGWorld,mipmap,false);
  803.     
  804.     SetGWorld (oldGW, oldGD);
  805.     UnlockPixels (hPixMap);
  806.     DisposeGWorld (pGWorld);
  807. }
  808.  
  809.  
  810. /******************** GWORLD TO MIPMAP ********************/
  811. //
  812. // Creates a mipmap from an existing GWorld
  813. //
  814. // NOTE: Assumes that GWorld is 16bit!!!!
  815. //
  816. // OUTPUT: mipmap = new mipmap holding texture image
  817. //
  818.  
  819. void QD3D_GWorldToMipMap(GWorldPtr pGWorld, TQ3Mipmap *mipmap, Boolean pointToGWorld)
  820. {
  821. unsigned long             pictMapAddr;
  822. PixMapHandle             hPixMap;
  823. unsigned long             pictRowBytes;
  824. long                    width, height;
  825. short                    depth;
  826.     
  827.                 /* GET GWORLD INFO */
  828.                 
  829.     hPixMap = GetGWorldPixMap(pGWorld);                                // calc addr & rowbytes
  830.     
  831.     depth = (**hPixMap).pixelSize;                                    // get gworld depth
  832.     
  833.     pictMapAddr = (unsigned long )GetPixBaseAddr(hPixMap);
  834.     pictRowBytes = (unsigned long)(**hPixMap).rowBytes & 0x3fff;
  835.     width = ((**hPixMap).bounds.right - (**hPixMap).bounds.left);
  836.     height = ((**hPixMap).bounds.bottom - (**hPixMap).bounds.top);
  837.  
  838.             /* MAKE MIPMAP */
  839.  
  840.     if (pointToGWorld)    
  841.     {
  842.         LockPixels(hPixMap);                                        // we don't want this to move on us
  843.         mipmap->image = Q3MemoryStorage_NewBuffer ((unsigned char *) pictMapAddr, pictRowBytes * height,pictRowBytes * height);
  844.     }
  845.     else
  846.         mipmap->image = Q3MemoryStorage_New ((unsigned char *) pictMapAddr, pictRowBytes * height);
  847.         
  848.     if (mipmap->image == nil)
  849.         DoFatalAlert("\pQ3MemoryStorage_New Failed!");
  850.  
  851.     mipmap->useMipmapping = kQ3False;                            // not actually using mipmaps (just 1 srcmap)
  852.     if (depth == 16)
  853.         mipmap->pixelType = kQ3PixelTypeRGB16;                        
  854.     else
  855.         mipmap->pixelType = kQ3PixelTypeARGB32;                    // if 32bit, assume alpha
  856.     
  857.     mipmap->bitOrder = kQ3EndianBig;
  858.     mipmap->byteOrder = kQ3EndianBig;
  859.     mipmap->reserved = nil;
  860.     mipmap->mipmaps[0].width = width;
  861.     mipmap->mipmaps[0].height = height;
  862.     mipmap->mipmaps[0].rowBytes = pictRowBytes;
  863.     mipmap->mipmaps[0].offset = 0;
  864. }
  865.  
  866.